package com.asdhawaii.ics111game.person;

import com.asdhawaii.ics111game.item.Item; 
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;

/**
 * Tests the Person class.
 * 
 * @author Branden Ogata
 *
 */

public class TestPerson
{
  /**
   * Tests the various methods in the Person class.
   * 
   */
 
  @Test
  public void test()
  {
    // Various Person instances for testing
    Person alpha = new Person("Alpha", "A young girl.", "The prototypical protagonist.");
    Person beta = new Person("Beta", "A female child.", "An energetic girl.");
    Person gamma = new Person("Gamma", "A calm, composed lady.", "Reserved and elegant.");
    Person bodyDouble = new Person("Gamma", "Looks very much like Gamma.", 
                                   "An impostor to deceive those searching for Gamma.");
    
    // Test the accessor methods
    assertEquals("Check getName()", alpha.getName(), "Alpha");
    assertEquals("Check getShortDescription()", beta.getShortDescription(), "A female child.");
    assertEquals("Check getLongDescription()", gamma.getLongDescription(), "Reserved and elegant.");
    
    // Test the energy methods
    // Alpha is sleepy
    alpha.updateEnergy(-64);
    assertEquals("Check energy after update", alpha.getEnergy(), 36.00, 0.01);
    // Beta is Beta
    beta.updateEnergy(200);
    assertEquals("Check energy overload", beta.getEnergy(), 100.00, 0.01);
    // Gamma remains as usual
    assertEquals("Check energy default", gamma.getEnergy(), 100.00, 0.01);
    assertTrue("Check isAlive", gamma.isAlive());
 
    // Test interactions with Item instances
    String cocoa = "hot chocolate";
    String confection = "marshmallows";
    String crackers = "graham crackers";
    Item hotChocolate = new Item(cocoa, "A mug of hot chocolate.", "The chocolate " +
                                 "shavings suggest that Gamma was the one who prepared this drink.",
                                 false, true, true, 5.12, 2.56, 32.00, false);
    Item marshmallows = new Item(confection, "A handful of marshmallows.", "An enticing " +
                                 "sugary treat.", true, false, true, 1.28, 1.28, 10.24, false);
    Item grahamCrackers = new Item(crackers, "Some graham crackers.", "I have no idea " +
                                   "what happened to Graham.", true, false, true, 1.28, 1.28,
                                   10.24, false);
    
    // Initially, none of the three are carrying anything
    assertTrue("Check initial inventory", alpha.getInventory().equals("") &&
                                          beta.getInventory().equals("") &&
                                          gamma.getInventory().equals(""));
    
    // Give the hot chocolate first
    alpha.addItem(hotChocolate);
    beta.addItem(hotChocolate);
    gamma.addItem(hotChocolate);
    assertTrue("Check inventory after cocoa", alpha.getInventory().contains(cocoa) &&
                                              beta.getInventory().contains(cocoa) &&
                                              gamma.getInventory().contains(cocoa));
    
    // Then the foods
    alpha.addItem(marshmallows);
    alpha.addItem(grahamCrackers);
    beta.addItem(marshmallows);
    beta.addItem(grahamCrackers);
    gamma.addItem(marshmallows);
    gamma.addItem(grahamCrackers);
    assertTrue("Check inventory after food", alpha.getInventory().contains(confection) &&
                                             alpha.getInventory().contains(crackers) &&
                                             beta.getInventory().contains(confection) &&
                                             beta.getInventory().contains(crackers) &&
                                             gamma.getInventory().contains(confection) &&
                                             gamma.getInventory().contains(crackers));
    
    // Beta quickly eats all her food and drink,
    // Alpha eats the crackers and marshmallows, 
    // and Gamma drinks her hot chocolate
    beta.removeAll();
    alpha.removeItem(confection);
    alpha.removeItem(crackers);
    gamma.removeItem(cocoa);
    assertTrue("Check inventory after meal", alpha.getInventory().contains(cocoa) &&
                                             beta.getInventory().equals("") &&
                                             gamma.getInventory().contains(confection) &&
                                             gamma.getInventory().contains(crackers));
    
    // Test comparisons
    assertTrue("Check equality with equals: same object", alpha.equals(alpha));
    assertTrue("Check equality with equals: same name", gamma.equals(bodyDouble));
    assertFalse("Check inequality with equals: different names", beta.equals(gamma));
    assertEquals("Check equality with compareTo: same object", beta.compareTo(beta), 0);
    assertEquals("Check equality with compareTo: same name", bodyDouble.compareTo(gamma), 0);
    assertTrue("Check inequality with compareTo: less than", alpha.compareTo(beta) < 0);
    assertTrue("Check inequality with compareTo: greater than", gamma.compareTo(alpha) > 0);
    
    // Test hashcode
    assertEquals("Check equality with hashCode: same object", alpha.hashCode(), alpha.hashCode());
    assertEquals("Check equality with hashCode: same name", gamma.hashCode(), 
                 bodyDouble.hashCode());
    
  }
}
